﻿using JewererBasic.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace JewererBasic.BO
{
    public enum KindReciever
    {
        All,
        Bag,
        Staff,
        Order_Tree,
        Order_Component
    }

    #region View models
    public class BagExportInfor
    {
        public int Numb_Export { get; set; }
        public string Bag_Id { get; set; }
        public string Component_Id { get; set; }
        public double Weight { get; set; }
        public DateTime Date { get; set; }
        public string MC { get; set; }

        public static List<BagExportInfor> GetDatas(List<COMPONENT_EXPORTBAGDETAIL> lst)
        {
            List<BagExportInfor> result = new List<BagExportInfor>();

            foreach (var item in lst)
            {
                var history = new BagExportInfor();
                history.Bag_Id = item.COMPONENT_EXPORTBAG.IdBag;
                history.Component_Id = item.IdComponent;
                history.Date = item.COMPONENT_EXPORTBAG.DayMake;
                history.MC = item.COMPONENT_EXPORTBAG.IdCreater;
                history.Numb_Export = item.COMPONENT_EXPORTBAG.IdExport;
                history.Weight = item.Weight.Value;
                result.Add(history);
            }
            return (result.Count > 0 ? result : null);
        }
    }

    public class OrderTreeExportInfor
    {        
        public int Tree_Id { get; set; }
        public string Component_Id { get; set; }
        public double Export_Weight { get; set; }
        public DateTime Date { get; set; }
        public string MC { get; set; }
        public string Worker_Id { get; set; }
        public double Return_Weight { get; set; }

        public static List<OrderTreeExportInfor> GetDatas(List<ORDER_TREE_DETAIL> lst)
        {
            List<OrderTreeExportInfor> result = new List<OrderTreeExportInfor>();

            foreach (var item in lst)
            {
                var history = new OrderTreeExportInfor();
                history.Component_Id = item.Component_Id;
                history.Date = item.ORDER_TREE.DateMake;
                history.Export_Weight = item.ExportWeight;
                history.MC = item.ORDER_TREE.MC;
                history.Return_Weight = item.ReturnWeight;
                history.Tree_Id = item.Order_Tree_Detail_Id;
                history.Worker_Id = item.EMPLOYEE.Staff_Id;
                result.Add(history);
            }

            return (result.Count > 0 ? result : null);
        }
    }

    public class OrderComponentExportInfor
    {
        public int Order_Component_Detail_Id { get; set; }
        public string Main_Component_Id { get; set; }
        public string Slave_Component_Id { get; set; }
        public double Export_Weight { get; set; }
        public DateTime Date { get; set; }
        public string Worker_Id { get; set; }
        public string MC { get; set; }

        public static List<OrderComponentExportInfor> GetDatas(List<COMPONENT_ORDER_COM_MOLECULE_EXPORT> lst)
        {
            List<OrderComponentExportInfor> result = new List<OrderComponentExportInfor>();

            foreach (var item in lst)
            {
                var history = new OrderComponentExportInfor();
                history.Date = item.COMPONENT_ORDER_DETAIL.COMPONENT_ORDER.DateMake;
                history.Export_Weight = item.Export_Weight;
                history.Main_Component_Id = item.COMPONENT_ORDER_DETAIL.Component_Id;
                history.MC = item.COMPONENT_ORDER_DETAIL.COMPONENT_ORDER.MC;
                history.Order_Component_Detail_Id = item.Com_Order_Detail_Id;
                history.Slave_Component_Id = item.Com_Slaver_Id;
                history.Worker_Id = item.COMPONENT_ORDER_DETAIL.EMPLOYEE.Staff_Id;
                result.Add(history);
            }

            return (result.Count > 0 ? result : null);
        }
    }

    public class StaffExportInfor
    {
        public int Staff_Export_Id { get; set; }
        public string Component_Id { get; set; }
        public string Worker_Id { get; set; }
        public double Export_Weight { get; set; }
        public double Return_Weight { get; set; }
        public string MC { get; set; }
        public DateTime Date { get; set; }

        public static List<StaffExportInfor> GetDatas(List<COMPONENT_EXPORTSTAFFDETAIL> lst)
        {
            List<StaffExportInfor> result = new List<StaffExportInfor>();

            foreach (var item in lst)
            {
                var history = new StaffExportInfor();
                history.Component_Id = item.IdComponent;
                history.Date = item.COMPONENT_EXPORTSTAFF.DayMake;
                history.Export_Weight = item.Weight;
                history.MC = item.COMPONENT_EXPORTSTAFF.IdCreater;
                history.Return_Weight = item.ReturnWeight;
                history.Staff_Export_Id = item.IdExport;
                history.Worker_Id = item.COMPONENT_EXPORTSTAFF.EMPLOYEE.Staff_Id;
                result.Add(history);
            }

            return (result.Count > 0 ? result : null);
        }
    }

    public class ComponentImportInfor
    {
        public int Id_Import { get; set; }
        public DateTime Date { get; set; }
        public double Weight { get; set; }
        public string Component_Id { get; set; }
        public string Reason { get; set; }
        public string MC { get; set; }

        public static List<ComponentImportInfor> GetDatas(List<COMPONENT_IMPORTDETAIL> lst)
        {
            List<ComponentImportInfor> result = new List<ComponentImportInfor>();

            foreach (var item in lst)
            {
                var history = new ComponentImportInfor();
                history.Component_Id = item.IdComponent;
                history.Date = item.COMPONENT_IMPORT.DayMake;
                history.Id_Import = item.COMPONENT_IMPORT.IdImport;
                history.MC = item.COMPONENT_IMPORT.IdCreater;
                history.Weight = item.Weight;
                result.Add(history);
            }

            return (result.Count > 0 ? result : null);
        }
    }

    public class OrderTreeImportDetail
    {
        public int Tree_Id { get; set; }
        public string Component_Id { get; set; }
        public double Return_Weight { get; set; }
        public DateTime Date { get; set; }
        public string Worker_Id { get; set; }
        public string MC { get; set; }

        public static List<OrderTreeImportDetail> GetDatas(List<ORDER_TREE_DETAIL> lst)
        {
            List<OrderTreeImportDetail> result = new List<OrderTreeImportDetail>();

            foreach (var item in lst)
            {
                var history = new OrderTreeImportDetail();
                history.Component_Id = item.Component_Id;
                history.Date = item.ORDER_TREE.DateMake;
                history.MC = item.ORDER_TREE.MC;
                history.Tree_Id = item.Order_Tree_Detail_Id;
                history.Worker_Id = item.EMPLOYEE.Staff_Id;

                result.Add(history);
            }

            return (result.Count > 0 ? result : null);
        }
    }

    public class OrderComponentImportInfor
    {
        public int Bag_Code { get; set; }
        public double Return_Weight { get; set; }
        public string Component_Id { get; set; }
        public DateTime Date { get; set; }
        public string Worker_Id { get; set; }
        public string MC { get; set; }
        public string ListMolecule { get; set; }

        public static List<OrderComponentImportInfor> GetDatas(List<COMPONENT_ORDER_DETAIL> lst)
        {
            List<OrderComponentImportInfor> result = new List<OrderComponentImportInfor>();

            foreach (var item in lst)
            {
                var history = new OrderComponentImportInfor();
                history.Bag_Code = item.Id;
                history.Component_Id = item.Component_Id;
                history.Date = item.COMPONENT_ORDER.DateMake;
                history.MC = item.COMPONENT_ORDER.MC;
                history.Return_Weight = item.Return_Weight;
                history.Worker_Id = item.EMPLOYEE.Staff_Id;
                history.ListMolecule = "";
                foreach (var detail in item.COMPONENT_ORDER_COM_MOLECULE_EXPORT)
                {
                    history.ListMolecule += detail.Com_Slaver_Id + ":" + detail.Export_Weight + "\r\n";
                }

                result.Add(history);
            }

            return (result.Count > 0 ? result : null);
        }
    }
    #endregion

    public class ComponentHistoryModel
    {
        [DataType(DataType.Date)]
        public DateTime? TimeFrom { get; set; }
        [DataType(DataType.Date)]
        public DateTime? TimeTo { get; set; }
        public string Component_Id { get; set; }
        public string Kind_Reciever { get; set; } // bag/order_tree/order_component/staff
        public string TypeReport { get; set; }// import or export

        public List<BagExportInfor> ExportBag { get; set; }
        public List<StaffExportInfor> ExportStaff { get; set; }
        public List<OrderTreeExportInfor> ExportOrderTree { get; set; }
        public List<OrderComponentExportInfor> ExportOrderComponent { get; set; }

        public List<ComponentImportInfor> ImportComponent { get; set; }
        public List<OrderTreeImportDetail> ImportOrderTree { get; set; }
        public List<OrderComponentImportInfor> ImportOrderComponent { get; set; }
    }

    public class ComponentHistoryBO
    {
        public static ComponentHistoryModel GetComponentExport(ComponentHistoryModel model)
        {
            if (model.TypeReport.Equals("Export"))
            {
                #region Export
                if (model.Kind_Reciever.Equals(KindReciever.All.ToString()))
                {
                    model.ExportBag = QueryExportBag(model);
                    model.ExportOrderComponent = QueryExportOrderComponent(model);
                    model.ExportOrderTree = QueryExportOrderTree(model);
                    model.ExportStaff = QueryExportStaff(model);
                }
                else if (model.Kind_Reciever.Equals(KindReciever.Bag.ToString()))
                {
                    model.ExportBag = QueryExportBag(model);
                }
                else if (model.Kind_Reciever.Equals(KindReciever.Order_Component.ToString()))
                {
                    model.ExportOrderComponent = QueryExportOrderComponent(model);
                }
                else if (model.Kind_Reciever.Equals(KindReciever.Order_Tree.ToString()))
                {
                    model.ExportOrderTree = QueryExportOrderTree(model);
                }
                else if (model.Kind_Reciever.Equals(KindReciever.Staff.ToString()))
                {
                    model.ExportStaff = QueryExportStaff(model);
                }
                #endregion
            }
            else
            {
                #region Import
                if (model.Kind_Reciever.Equals(KindReciever.All.ToString()))
                {
                    model.ImportOrderComponent = QueryImportOrderComponent(model);
                    model.ImportOrderTree = QueryImportOrderTree(model);
                    model.ImportComponent = QueryImportComponent(model);
                }                
                else if (model.Kind_Reciever.Equals(KindReciever.Order_Component.ToString()))
                {
                    model.ImportOrderComponent = QueryImportOrderComponent(model); 
                }
                else if (model.Kind_Reciever.Equals(KindReciever.Order_Tree.ToString()))
                {
                    model.ImportOrderTree = QueryImportOrderTree(model);
                }
                else if (model.Kind_Reciever.Equals(KindReciever.Staff.ToString()))
                {
                    model.ImportComponent = QueryImportComponent(model);
                }
                #endregion
            }           
            return model;
        }

        #region Helper functions Export
        private static List<BagExportInfor> QueryExportBag(ComponentHistoryModel model)
        {
            MSQDBEntities db = new MSQDBEntities();
            List<COMPONENT_EXPORTBAGDETAIL> lstBagExport = (from d in db.COMPONENT_EXPORTBAGDETAIL
                                                            where
                                                            (model.Component_Id == null || model.Component_Id.Equals(d.IdComponent))
                                                            && (model.TimeTo == null || DateTime.Compare(d.COMPONENT_EXPORTBAG.DayMake, model.TimeTo.Value) <= 0)
                                                            && (model.TimeFrom == null || DateTime.Compare(d.COMPONENT_EXPORTBAG.DayMake, model.TimeFrom.Value) >= 0)
                                                            select d).ToList();
            return BagExportInfor.GetDatas(lstBagExport);
        }

        private static List<StaffExportInfor> QueryExportStaff(ComponentHistoryModel model)
        {
            MSQDBEntities db = new MSQDBEntities();
            List<COMPONENT_EXPORTSTAFFDETAIL> lstStaffExport = (from d in db.COMPONENT_EXPORTSTAFFDETAIL
                                                                where
                                                                (model.Component_Id == null || model.Component_Id.Equals(d.IdComponent))
                                                                && (model.TimeTo == null || DateTime.Compare(d.COMPONENT_EXPORTSTAFF.DayMake, model.TimeTo.Value) <= 0)
                                                                && (model.TimeFrom == null || DateTime.Compare(d.COMPONENT_EXPORTSTAFF.DayMake, model.TimeFrom.Value) >= 0)
                                                                select d).ToList();
            return StaffExportInfor.GetDatas(lstStaffExport);
        }

        private static List<OrderTreeExportInfor> QueryExportOrderTree(ComponentHistoryModel model)
        {
            MSQDBEntities db = new MSQDBEntities();
            List<ORDER_TREE_DETAIL> lstTreeExport = (from d in db.ORDER_TREE_DETAIL
                                                     where
                                                     d.Finish != -1// has exported
                                                     && (model.Component_Id == null || model.Component_Id.Equals(d.Component_Id))
                                                     && (model.TimeTo == null || DateTime.Compare(d.ORDER_TREE.DateMake, model.TimeTo.Value) <= 0)
                                                     && (model.TimeFrom == null || DateTime.Compare(d.ORDER_TREE.DateMake, model.TimeFrom.Value) >= 0)
                                                     select d).ToList();
            return OrderTreeExportInfor.GetDatas(lstTreeExport);
        }

        private static List<OrderComponentExportInfor> QueryExportOrderComponent(ComponentHistoryModel model)
        {
            MSQDBEntities db = new MSQDBEntities();
            List<COMPONENT_ORDER_COM_MOLECULE_EXPORT> lstMoleculeExport = (from d in db.COMPONENT_ORDER_COM_MOLECULE_EXPORT
                                                                           where
                                                                           d.IsExported == 1
                                                                           && (model.Component_Id == null || model.Component_Id.Equals(d.Com_Slaver_Id))
                                                                           && (model.TimeTo == null || DateTime.Compare(d.TimeMake, model.TimeTo.Value) <= 0)
                                                                           && (model.TimeFrom == null || DateTime.Compare(d.TimeMake, model.TimeFrom.Value) >= 0)
                                                                           select d).ToList();
            return OrderComponentExportInfor.GetDatas(lstMoleculeExport);
        }
        #endregion

        #region Helper functions Import

        private static List<ComponentImportInfor> QueryImportComponent(ComponentHistoryModel model)
        {
            MSQDBEntities db = new MSQDBEntities();
            List<COMPONENT_IMPORTDETAIL> lstBagExport = (from d in db.COMPONENT_IMPORTDETAIL
                                                            where
                                                            (model.Component_Id == null || model.Component_Id.Equals(d.IdComponent))
                                                            && (model.TimeTo == null || DateTime.Compare(d.COMPONENT_IMPORT.DayMake, model.TimeTo.Value) <= 0)
                                                            && (model.TimeFrom == null || DateTime.Compare(d.COMPONENT_IMPORT.DayMake, model.TimeFrom.Value) >= 0)
                                                            select d).ToList();
            return ComponentImportInfor.GetDatas(lstBagExport);
        }

        private static List<OrderTreeImportDetail> QueryImportOrderTree(ComponentHistoryModel model)
        {
            MSQDBEntities db = new MSQDBEntities();
            List<ORDER_TREE_DETAIL> lst = (from d in db.ORDER_TREE_DETAIL
                                                            where
                                                            (model.Component_Id == null || model.Component_Id.Equals(d.Component_Id))
                                                            && (model.TimeTo == null || DateTime.Compare(d.ORDER_TREE.DateMake, model.TimeTo.Value) <= 0)
                                                            && (model.TimeFrom == null || DateTime.Compare(d.ORDER_TREE.DateMake, model.TimeFrom.Value) >= 0)
                                                            select d).ToList();
            return OrderTreeImportDetail.GetDatas(lst);
        }

        private static List<OrderComponentImportInfor> QueryImportOrderComponent(ComponentHistoryModel model)
        {
            MSQDBEntities db = new MSQDBEntities();
            List<COMPONENT_ORDER_DETAIL> lst = (from d in db.COMPONENT_ORDER_DETAIL
                                                            where
                                                            (model.Component_Id == null || model.Component_Id.Equals(d.Component_Id))
                                                            && (model.TimeTo == null || DateTime.Compare(d.COMPONENT_ORDER.DateMake, model.TimeTo.Value) <= 0)
                                                            && (model.TimeFrom == null || DateTime.Compare(d.COMPONENT_ORDER.DateMake, model.TimeFrom.Value) >= 0)
                                                            select d).ToList();
            return OrderComponentImportInfor.GetDatas(lst);
        }
        #endregion
    }
}